/*
 * Paquete que posee las clases necesarias para comparar dos strings,
 * el primer string representa la clave y el segundo la respuesta
 * and open the template in the editor.
 */
package pio.action.administrador.inscripcion.utils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 *Clase Key.
 */
public class Key {
private String name=null;
private String key =null;    
private String optionsValid =null;    
private String optionsEmpty =null;    
private int increment=1;
private int decrement=0;
private List errs;

/**
 * @param name representa el nombre de la clave Ej. ClaveRaven(20-01-2013).
 * @param optionsValid representa un strings de los posibles valores que puede
 * tener el parametro key Ej abcd.
 * @param key representa la clave string o texto Ej. AAABBCCCDDDD. 
 * @param optionsEmpty representa un strings de los valores de respuesta que no 
 * son comparables o atribuyen decremento Ej e.
 * @param decrement representa un entero que se asigna cuando la comparacion de 
 * la clave y respuesta no hacen match o cuando la respuesta posee un valor del 
 * parametro optionsEmpty. Las opciones empty se refieren a opciones como 
 * -no sabe - no contesta que responde un estudiante en un examen.
 * Ej "e"  . Si la respuesta es "e" entonces se suma el decremento que 
 * por defecto es 0
 * @param increment representa un entero que se asigna cuando la comparacion de 
 * la clave y respuesta hacen match. Valor por defecto 1.
 * @param errs representa una lista de posibles errores encontrados en la clave, 
 * respuesta o metodos y funciones que involucren a estas.
 */
public  Key(String name, String key, String optionsV, String optionsE, int inc,
        int dec, List errs){
    this.name=name;
    this.key=key;
    this.optionsValid=optionsV;
    this.optionsEmpty=optionsE;
    this.increment=inc;
    this.decrement=dec;
    this.errs=errs;
        }
   /**
    * @return the Key
    */
    public String getKey() {
        return key;
    }

    /**
     * @param Key the Key to set
     */
    public void setKey(String key) {
        this.key = key;
    }

    /**
     * @return the errs
     */
    public List getErrs() {
        return errs;
    }

    /**
     * @param errs the errs to set
     */
    public void setErrs(List errs) {
        this.errs = errs;
    }
 
     /**
     * @return the errs en pantalla
     */
    public void printlnErrs() {
        int i=0;
        Iterator ite=(Iterator)errs.iterator();
        while (ite.hasNext()){
        System.out.println("\n"+(i+1)+"."+ite.next()+"\n");
        i++;
        }
       System.out.println(""); 
    }

 
    /**
     * @return the optionsValid
     */
    public String getOptionsValid() {
        return optionsValid;
    }

    /**
     * @param optionsValid the optionsValid to set
     */
    public void setOptionsValid(String optionsValid) {
        this.optionsValid = optionsValid;
        if (optionsValid==null){
        this.errs.add("Error:: Opciones de respuestas posibles para la clave"+
                this.name+"no fueron establecidas");
        }
        if (optionsValid.isEmpty()){
        this.errs.add("Error:: Opciones de respuestas posibles para la clave"+
                this.name+"no pueden asignarse vacias");
        }
    }

    /**
     * @return the optionsEmpty
     */
    public String getOptionsEmpty() {
        return optionsEmpty;
    }

    /**
     * @param optionsEmpty the optionsEmpty to set
     */
    public void setOptionsEmpty(String optionsEmpty) {
        this.optionsEmpty = optionsEmpty;
    }

    /**
     * @return the increment
     */
    public int getIncrement() {
        return increment;
    }

    /**
     * @param increment the increment to set
     */
    public void setIncrement(int increment) {
        this.increment = increment;
    }

    /**
     * @return the decrement
     */
    public int getDecrement() {
        return decrement;
    }

    /**
     * @param decrement the decrement to set
     */
    public void setDecrement(int decrement) {
        this.decrement = decrement;
    }
    
    /**@return Las siguientes opciones:
     * 0 si no coincide con alguna de las opciones validas del objeto clave
     * 1 si coincide con al menos 1 de las opciones validas del objeto clave
     */
      public int isInRange(Character option){
        if(this.optionsValid.contains(option.toString())) {
             return 1;
         }
        else if(this.optionsEmpty.contains(option.toString())) {
            return -1;
         }else {
            return 0;
        }   
     }
     
     /** @return Las siguientes opciones:
     * 0 si option no coincide con alguna de las opciones validas del objeto 
     * clave
     * 1 si option coincide con al menos 1 de las opciones validas del objeto 
     * clave
     * 2 si option coincide con al menos 1 de las opciones (Empty) del objeto 
     * clave
     */
     public int isInRangeStr(Character option){
        if(this.optionsValid.contains(option.toString())) {
             return 1;
         }
        else if (this.optionsEmpty.contains(option.toString())) {
             return 2;
         } 
        else {
             return 0;
         }  
     }

 

     /** Se verifica que los strings no sean vacios 
      * posean el mismo tamaño, no posean caracteres
      * extraños y se calcula el numero de tokens iguales
      * que existen en posiciones iguales con respecto a los 
      * dos strings.
      * @return Un entero mayor o igual  a 0
     */
  public int countSuccess(Key key, String strB, String dato){
    int success=0,i=0,intA,intB;
    char tokenA,tokenB;
    String strA = key.getKey();
    int lenA=strA.length(),lenB=strB.length();
        if(lenA==0 || lenB==0){
        key.errs.add("Error: "+dato+" la clave o respuesta son vacias ");
        return -1;
        }
        if(lenA!=lenB){
        key.errs.add("Error: "+dato+" La clave tiene "+lenA+" tokens y la respuesta "+
                lenB+". Deben ser iguales, corrija");
        return -1;
        }
        try{
        while (i<lenA){
            tokenA= strA.charAt(i);
            tokenB= strB.charAt(i);
            intA=key.isInRange(tokenA);
            if (intA==0) {
                this.errs.add("Error: "+dato+" Existe un caracter extraño ("+tokenA
                        +") en la clave"); 
                return -1;
            }else if(intA<=-1 ){
                this.errs.add("Error: "+dato+" La clave posee un caracter que sólo "
                        + "debe aparecer en la respuesta ("+tokenA
                        +") en la clave"); 
                return -1;
            }
            
            intB=key.isInRangeStr(tokenB);
            if (intB<=0) {
                this.errs.add("Error: "+dato+" Existe un caracter extraño ("+tokenB
                        +") en las respuestas"); 
                return -1;
            }
            else if(intB==2){
                i++;
                success=success+this.decrement;
                //System.out.println("continue");
                continue;
            }               
            if(tokenA==tokenB){
                success=success+this.increment;
            }
            i++;
        }   
        return success;
        }catch(IndexOutOfBoundsException e){
            System.out.println("Excepcion:: Indice fuera de limites");
            System.exit(-1);
            return -1;    
        }  
    } 
public int countSuccess2(Key key, String strB, ArrayList divitions, ArrayList results, String dato) {
    Iterator div;
    String keyS,strC;
    int k=0,l,result,aux;
    String key2=(String)key.getKey();
    if (!divitions.isEmpty()){
    div = divitions.iterator();
        while(div.hasNext()){
            l=(Integer)div.next();
        keyS=(String)key2.substring(k, l);
        strC=(String)strB.substring(k, l);
        key.setKey(keyS);
        result=countSuccess(key, strC, dato);
        if(results!=null){
        results.add((int)result);
        }else{
        return -1;
        }
        k=l;
        }
    }
    key.setKey(key2);
return 1;
}

}